using System;
using System.Windows.Forms;
using Microsoft.Data.ConnectionUI;
using Sixeyed.CodeGeneration.Metadata.Database.Sources;
using Sixeyed.CodeGeneration.Metadata.FileSystem.Sources;
using Sixeyed.CodeGeneration.Metadata.Interfaces;
using Sixeyed.CodeGeneration.UI.Enums;

namespace Sixeyed.CodeGeneration.UI
{
    /// <summary>
    /// Dialog window for capturing metadata source Uri
    /// </summary>
    /// <remarks>
    /// For known metadata sources, can show a custom dialog box for selecting the Uri
    /// </remarks>
    public partial class SourceUri : Form
    {
        private IMetadataSource _source;
        private UriDialog _uriDialog;

        /// <summary>
        /// Default constructor
        /// </summary>
        public SourceUri()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Gets/sets the metadata source to update
        /// </summary>
        public IMetadataSource Source
        {
            get { return _source; }
            set 
            { 
                _source = value;
                this.Setup();
            }
        }

        private void Setup()
        {
            this.txtUri.Text = string.Empty;
            this.btnDialog.Visible = false;
            if (this.Source != null)
            {
                this.txtUri.Text = this.Source.Uri;
                this.btnDialog.Visible = this.SourceHasDialogSupport();
                this.lblUriName.Text = this.Source.UriDisplayName;
            }
        }

        private bool SourceHasDialogSupport()
        {
            this._uriDialog = UriDialog.Null;
            //REFACTOR - make this configurable:
            if (this.Source.GetType() == typeof(SqlServerSource))
            {
                this._uriDialog = UriDialog.SqlServerConnectionString;
            }
            else if (this.Source.GetType() == typeof(FileSource))
            {
                this._uriDialog = UriDialog.FilePath;
            }
            else if (this.Source.GetType() == typeof(DirectorySource))
            {
                this._uriDialog = UriDialog.DirectoryPath;
            }
            return (this._uriDialog != UriDialog.Null);
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            this.Source.Uri = this.txtUri.Text;
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        private void ShowDirectoryDialog()
        {
            FolderBrowserDialog browserDialog = new FolderBrowserDialog();
            if (browserDialog.ShowDialog() == DialogResult.OK)
            {
                this.txtUri.Text = browserDialog.SelectedPath;
            }
        }

        private void ShowFileDialog()
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                this.txtUri.Text = fileDialog.FileName;
            }
        }

        private void ShowSqlServerConnectionDialog()
        {
            DataConnectionDialog connectionDialog = new DataConnectionDialog();
            connectionDialog.DataSources.Add(DataSource.SqlDataSource);
            connectionDialog.SelectedDataSource = DataSource.SqlDataSource;
            connectionDialog.SelectedDataProvider = DataProvider.SqlDataProvider;

            if (DataConnectionDialog.Show(connectionDialog) == DialogResult.OK)
            {
                this.txtUri.Text = connectionDialog.ConnectionString;
            }
        }

        private void btnDialog_Click(object sender, EventArgs e)
        {
            switch (this._uriDialog)
            {
                case UriDialog.SqlServerConnectionString:
                    this.ShowSqlServerConnectionDialog();
                    break;
                case UriDialog.FilePath:
                case UriDialog.DirectoryPath:
                    this.ShowDirectoryDialog();
                    break;
            }
        }
    }
}